using System;
using System.Collections.Generic;
using System.Reflection;
namespace ServiceStack
{
	public static class EnumExtensions
	{
		public static string ToDescription(this Enum @enum)
		{
			MemberInfo[] member = @enum.GetType().GetMember(@enum.ToString());
			if (member.Length != 0)
			{
				string description = member[0].GetDescription();
				if (description != null)
				{
					return description;
				}
			}
			return @enum.ToString();
		}
		public static List<string> ToList(this Enum @enum)
		{
			return new List<string>(Enum.GetNames(@enum.GetType()));
		}
		public static TypeCode GetTypeCode(this Enum @enum)
		{
			return Type.GetTypeCode(Enum.GetUnderlyingType(@enum.GetType()));
		}
		public static bool Has<T>(this Enum @enum, T value)
		{
			switch (@enum.GetTypeCode())
			{
			case TypeCode.Byte:
				return ((byte)@enum & (byte)((object)value)) == (byte)((object)value);
			case TypeCode.Int16:
				return ((short)@enum & (short)((object)value)) == (short)((object)value);
			case TypeCode.Int32:
				return ((int)@enum & (int)((object)value)) == (int)((object)value);
			case TypeCode.Int64:
				return ((long)@enum & (long)((object)value)) == (long)((object)value);
			}
			throw new NotSupportedException("Enums of type {0}".Fmt(new object[]
			{
				@enum.GetType().Name
			}));
		}
		public static bool Is<T>(this Enum @enum, T value)
		{
			switch (@enum.GetTypeCode())
			{
			case TypeCode.Byte:
				return (byte)@enum == (byte)((object)value);
			case TypeCode.Int16:
				return (short)@enum == (short)((object)value);
			case TypeCode.Int32:
				return (int)@enum == (int)((object)value);
			case TypeCode.Int64:
				return (long)@enum == (long)((object)value);
			}
			throw new NotSupportedException("Enums of type {0}".Fmt(new object[]
			{
				@enum.GetType().Name
			}));
		}
		public static T Add<T>(this Enum @enum, T value)
		{
			switch (@enum.GetTypeCode())
			{
			case TypeCode.Byte:
				return (T)((object)((int)((byte)@enum | (byte)((object)value))));
			case TypeCode.Int16:
				return (T)((object)((int)((short)@enum | (short)((object)value))));
			case TypeCode.Int32:
				return (T)((object)((int)@enum | (int)((object)value)));
			case TypeCode.Int64:
				return (T)((object)((long)@enum | (long)((object)value)));
			}
			throw new NotSupportedException("Enums of type {0}".Fmt(new object[]
			{
				@enum.GetType().Name
			}));
		}
		public static T Remove<T>(this Enum @enum, T value)
		{
			switch (@enum.GetTypeCode())
			{
			case TypeCode.Byte:
				return (T)((object)((int)((byte)@enum & ~(int)((byte)((object)value)))));
			case TypeCode.Int16:
				return (T)((object)((int)((short)@enum & ~(int)((short)((object)value)))));
			case TypeCode.Int32:
				return (T)((object)((int)@enum & ~(int)((object)value)));
			case TypeCode.Int64:
				return (T)((object)((long)@enum & ~(long)((object)value)));
			}
			throw new NotSupportedException("Enums of type {0}".Fmt(new object[]
			{
				@enum.GetType().Name
			}));
		}
	}
}
